const { reject, reverse } = require("lodash");

// 实现一个promise队列----传入一个promise数组，一次串行执行并输出他们的成功或者失败结果
// 串行
function queuePromise(promiseArr) {
    return new Promise((resolve, reject) => {
        let arrLen = promiseArr.length;
        let resArr = [];
        if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组！', Array.isArray(promiseArr) , arrLen);
        let ArrStatus = promiseArr.every(item => {
            return item instanceof Promise;
        });
        if (!ArrStatus) return console.error('数组第每一项必须是promise');
        try {
            let num = 0;
            function run(num) {
                if (num >= arrLen) {
                    resolve(resArr);
                    return;
                };
                console.log('开始执行：'+num);
                promiseArr[num].then((res) => {
                        resArr.push({
                            status: 1,
                            res,
                        });
                        console.log(res + '=>');
                        run(++num);
                    }, err => {
                        console.log(err + '-->');
                        resArr.push({
                            status: 0,
                            err,
                        });
                        run(++num);
                    });
            };
            run(num);
        } catch (error) {
            reject(error);
        }
    })
};



let arr = [new Promise(resolve => {
    setTimeout(_ => {
        resolve('3s');
    }, 3000);
}), new Promise(resolve => {
    setTimeout(_ => {
        resolve('8s');
    }, 3000);
}), new Promise((resolve, reject) => {
    setTimeout(_ => {
        resolve('18s');
        // reject('18s');
    }, 3000);
})];

// queuePromise(arr).then(res => {
//     console.log('queuePromise=>', res);
// }).catch(err => {
//     console.log('queuePromise-err=>', err);
// });


// 并行 但是由于微任务机制它们执行纯在先后顺序
let quePromise =  (promiseArr) => {
    let arrLen = promiseArr.length;
    let resArr = [];
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组！', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        // console.log('quePromise+>', Array(...Array(arrLen).keys()));
        Array(...Array(arrLen).keys()).reduce((promise, index) => {
            console.log('------>', index, promise);
            return promiseArr[index].then(res=> {
                resArr.push({
                    status: 1,
                    res,
                });
                console.log(res + '=>');
                (index == arrLen - 1) && resolve(resArr);
            }, err => {
                resArr.push({
                    status: 0,
                    err,
                });
                console.log(err + '-->');
                (index == arrLen - 1) && resolve(resArr);
            });
        }, Promise.resolve('1'));
    });
}

quePromise(arr).then(res => {
    console.log('quePromise:', res);
})

// 实现promise.all----并行
let promiseAll = function(promiseArr) {
    let arrLen = promiseArr.length;
    let resoveCount = 0;
    let resArr = new Array(arrLen);
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组！', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        promiseArr.forEach((promise, index) => {
            promise.then(res => {
                resArr[index] = res;
                resoveCount ++;
                if (resoveCount === arrLen) resolve(resArr);
            }, err => {
                reject(err);
            });
        });
    });
};

// promiseAll(arr).then(res => {
//     console.log('promiseAll:', res);
// }, err=> {
//     console.log('promiseAll--err:', err);

// });


// promise.race ---并行

function promiseRace(promiseArr) {
    let arrLen = promiseArr.length;
    let status = false;
    if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组！', Array.isArray(promiseArr) , arrLen);
    let ArrStatus = promiseArr.every(item => {
        return item instanceof Promise;
    });
    if (!ArrStatus) return console.error('数组第每一项必须是promise');
    return new Promise((resolve, reject) => {
        try {
            promiseArr.forEach((item, index) => {
                if (!status) {
                    item.then(res => {
                        resolve(res);
                        status = true;
                    }, error => {
                        reject(error);
                    })
                };
            });
        } catch (error) {
            reject(error);
        }
    })
};


let raceArr = [
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----3s');
        }, 3000);
    }),
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----2s');
        }, 2000);
    }),
    new Promise((resolve, reject) => {
        setTimeout(_ => {
            resolve('race-----5s');
        }, 5000);
    }),
];

// promiseRace(raceArr).then(res => {
//     console.log('promiseRace=>', res);
// }, err => {
//     console.log('promiseRace--err=>', err);

// })
